﻿/*
 * @author: wizardc
 */

using System;
using System.Collections.Generic;
using Dou.Utils;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Dou.UI
{
    /// <summary>
    /// UI 对象复制器
    /// 注：支持直接设置数据源的方式来实现
    /// </summary>
    [DisallowMultipleComponent]
    public class UIDataDuplicator : UIBehaviour
    {
        /// <summary>
        /// Item 创建时回调
        /// </summary>
        public event Action<GameObject, object, int> onItemInit;
        
        /// <summary>
        /// Item 更新时回调
        /// </summary>
        public event Action<GameObject, object, int> onItemUpdate;
        
        /// <summary>
        /// Item 失效时回调
        /// </summary>
        public event Action<GameObject, int> onItemDisable;
        
        /// <summary>
        /// 模板
        /// </summary>
        public GameObject template;
        
        /// <summary>
        /// 容器
        /// </summary>
        public Transform container;

        private List<GameObject> _items = new List<GameObject>();
        private ICollection _dataProvider;

        public ICollection dataProvider
        {
            set
            {
                if (_dataProvider != value)
                {
                    if (_dataProvider != null)
                    {
                        ClearItems();
                    }
                    _dataProvider = value;
                    if (_dataProvider != null)
                    {
                        Refresh();
                    }
                }
            }
            get => _dataProvider;
        }
        
        protected override void Awake()
        {
            if (template != null)
            {
                template.SetActive(false);
            }
        }

        protected override void Start()
        {
            Refresh();
        }
        
        public GameObject GetItem(int index)
        {
            if (index < 0 || index >= _dataProvider.count)
            {
                return null;
            }
            return _items[index];
        }
        
        /// <summary>
        /// 数据源自身数据改变时，调用该方法对显示列表进行刷新
        /// </summary>
        public void Refresh()
        {
            if (template == null || container == null)
            {
                Log.Warning("没有设定模版或容器！");
                return;
            }
            
            var dataCount = _dataProvider.count;
            
            // 多余的项目需要销毁
            if (_items.Count > dataCount)
            {
                for (var i = _items.Count - 1; i >= dataCount; i--)
                {
                    _items.RemoveAt(i);
                    onItemDisable?.Invoke(_items[i], i);
                    GameObject.Destroy(_items[i]);
                }
            }
            
            // 更新或创建项目
            for (var i = 0; i < dataCount; i++)
            {
                if (_items.Count > i)
                {
                    onItemUpdate?.Invoke(_items[i], _dataProvider.GetItemAt(i), i);
                }
                else
                {
                    var item = GameObject.Instantiate(template, container);
                    item.name = template.name + "(" + i + ")";
                    item.SetActive(true);
                    _items.Add(item);
                    onItemInit?.Invoke(item, _dataProvider.GetItemAt(i), i);
                    onItemUpdate?.Invoke(item, _dataProvider.GetItemAt(i), i);
                }
            }
        }
        
        private void ClearItems()
        {
            var count = _dataProvider.count;
            if (count > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    var item = _items[i];
                    onItemDisable?.Invoke(item, i);
                    GameObject.Destroy(item);
                }
                _items.Clear();
            }
        }
        
        protected override void OnDestroy()
        {
            ClearItems();
        }
    }
}
